package com.frogs.ucenter.v1.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.frogs.framework.component.cache.Cache;
import com.frogs.framework.util.PageList;
import com.frogs.framework.util.StringUtil;
import com.frogs.system.util.ApiUrlParamEnum;
import com.frogs.system.util.ApplicablePlatformEnum;
import com.frogs.system.util.FullGoodsStatusEnum;
import com.frogs.system.util.GoodsCheckStatusEnum;
import com.frogs.system.util.GoodsStatusEnum;
import com.frogs.system.util.ShoppingCartCreateTypeEnum;
import com.frogs.system.util.ShoppingCartStatusEnum;
import com.frogs.system.web.api.request.Request;
import com.frogs.system.web.api.response.Response;
import com.frogs.system.web.exception.ServiceOperationException;
import com.frogs.ucenter.component.RequestApiHelper;
import com.frogs.ucenter.dao.ShoppingCartDao;
import com.frogs.ucenter.dao.UserShoppingRelationDao;
import com.frogs.ucenter.entity.ShoppingCart;
import com.frogs.ucenter.entity.UserShippingAddress;
import com.frogs.ucenter.entity.UserShoppingCart;
import com.frogs.ucenter.entity.UserShoppingRelation;
import com.frogs.ucenter.v1.request.UserShoppingCartAddRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartBatchAddRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartDeleteRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartListRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartMergeRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartSumRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartTopListRequest;
import com.frogs.ucenter.v1.request.UserShoppingCartUpdateRequest;
import com.frogs.ucenter.v1.response.AddResponse;
import com.frogs.ucenter.v1.response.DefaultResponse;
import com.frogs.ucenter.v1.response.DeleteResponse;
import com.frogs.ucenter.v1.response.ListResponse;
import com.frogs.ucenter.v1.response.PageListResponse;
import com.frogs.ucenter.v1.response.ShowResponse;
import com.frogs.ucenter.v1.response.UpdateResponse;
import com.frogs.ucenter.v1.service.UserShoppingCartService;
import com.frogs.ucenter.v1.util.ApiConstants;

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
@Service(ApiConstants.VERSION+"userShoppingCartService")
public class UserShoppingCartServiceImpl implements UserShoppingCartService {
	
	private static final Logger log = LoggerFactory.getLogger(UserShoppingCartServiceImpl.class);

    @Resource
    private ShoppingCartDao shoppingCartDao;
    
    @Resource
    private UserShoppingRelationDao userShoppingRelationDao;
    
    @Resource
    private RequestApiHelper requestApiHelper;
    
    @Resource(name="xmemcached")
	private Cache cache;

	private final int cacheLifeCycle = 1;

    
    /**
     * 查询购物车中商品总数
     * @param request
     * @return
     */
    @Override
    public Response getSum(Request request) throws Exception {
    	UserShoppingCartSumRequest sumRequest = (UserShoppingCartSumRequest)request;
    	ShowResponse<Integer> response = new ShowResponse<Integer>();
    	try {
	    	
	        
	    	Map<String, Object> params = new HashMap<String , Object>();

			if(sumRequest.getUserId() > 0)
				params.put("eqUserId", sumRequest.getUserId());//登录用户
			else
				params.put("eqUserTraceId", sumRequest.getUserTraceId());//游客用户
			
	    	if(sumRequest.getApplicablePlatformId() > ApplicablePlatformEnum.ALL.getId())
	    		params.put("eqApplicablePlatformId", sumRequest.getApplicablePlatformId());
	    	
	    	params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
			
	    	Integer sum = shoppingCartDao.selectSumNumberByMap(params);
    	
	    	response.setInfo(sum);
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
    	
    }
    
    /**
     * 获取用户购物车列表
     * 注意：
     * 1.只查询未删除的购物车商品
     * 2.查用户在每个平台中购物车的商品列表
     * 
     */
    @Override
    public Response getTopList(Request request) throws Exception {
    	ListResponse<UserShoppingCart> response = new ListResponse<UserShoppingCart>();
        
    	try {
    		UserShoppingCartTopListRequest listRequest = (UserShoppingCartTopListRequest)request;
	    	Map<String, Object> params = new HashMap<String , Object>();

			if(listRequest.getUserId() > 0)
				params.put("eqUserId", listRequest.getUserId());//登录用户
			else
				params.put("eqUserTraceId", listRequest.getUserTraceId());//游客用户
	    	
	    	if(listRequest.getApplicablePlatformId() > ApplicablePlatformEnum.ALL.getId())
	    		params.put("eqApplicablePlatformId", listRequest.getApplicablePlatformId());
	    	params.put("orderByClause", " id desc ");
	    	
	    	List<UserShoppingCart> list = new ArrayList<UserShoppingCart>();
	    	List<UserShoppingRelation> userShoppingRelationList = userShoppingRelationDao.selectByMap(params, 1 , 20, false);
	    	for(UserShoppingRelation relation : userShoppingRelationList){
	    		UserShoppingCart userShopping = new UserShoppingCart();
	    		userShopping.setUserShoppingRelation(relation);
	    		
	    		params.clear();
	    		if(listRequest.getUserId() > 0)
					params.put("eqUserId", listRequest.getUserId());//登录用户
				else
					params.put("eqUserTraceId", listRequest.getUserTraceId());//游客用户
		    	
	    		if(!StringUtil.isEmpty(listRequest.getExpandCode())) {
	    			params.put("eqExpandCode" , listRequest.getExpandCode());
	    		}
		    	if(!StringUtil.isEmpty(listRequest.getSubExpandCode())) {
	    			params.put("eqSubExpandCode" , listRequest.getSubExpandCode());
	    		}
	    		params.put("eqShoppingCartId", relation.getId());
	    		params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
	    		List<ShoppingCart> shoppingCartList = shoppingCartDao.selectByMap(params, 0, 10000, false);
	    		userShopping.setShoppingCartList(shoppingCartList);
	    		list.add(userShopping);
	    	}
	    	
	        response.setList(list);
	        response.setTip("用户购物车查询成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
    }
    
    /**
     * 获取用户购物车列表
     * 注意：只查询未删除的购物车商品
     */
    @Override
    public Response getPageList(Request request) throws Exception {
    	PageListResponse<ShoppingCart> response = new PageListResponse<ShoppingCart>();
        
    	try {
    		UserShoppingCartListRequest listRequest = (UserShoppingCartListRequest)request;
	    	Map<String, Object> params = new HashMap<String , Object>();

	    	if(listRequest.getUserId() > 0)
				params.put("eqUserId", listRequest.getUserId());//登录用户
			else
				params.put("eqUserTraceId", listRequest.getUserTraceId());//游客用户
	    	
	    	if(!StringUtil.isEmpty(listRequest.getExpandCode())) {
    			params.put("eqExpandCode" , listRequest.getExpandCode());
    		}
	    	
	    	if(!StringUtil.isEmpty(listRequest.getSubExpandCode())) {
    			params.put("eqSubExpandCode" , listRequest.getSubExpandCode());
    		}
	    	
	    	if(listRequest.getApplicablePlatformId() > ApplicablePlatformEnum.ALL.getId())
	    		params.put("eqApplicablePlatformId", listRequest.getApplicablePlatformId());
	    	params.put("orderByClause", " id desc ");
	    	
	    	params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
    		
	    	PageList<ShoppingCart> shoppingCartList = shoppingCartDao.selectByMap(params, listRequest.getPageNum(), listRequest.getNumPerPage());
    		response.setList(shoppingCartList);
    		response.setPageTurn(shoppingCartList.getPageTurn());
	        response.setTip("用户购物车查询成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
    }

    /**
     * 添加购物车商品
     */
	@Override
	public Response insert(Request request) throws Exception  {
		AddResponse<ShoppingCart> response = new AddResponse<ShoppingCart>();
		UserShoppingCartAddRequest addRequest = (UserShoppingCartAddRequest)request;
    	try {
    		//校验购物车记录添加状态
    		shoppingCartAsync(addRequest.getUserId(), addRequest.getUserTraceId(), addRequest.getApplicablePlatformId());
    		
    		UserShoppingRelation relation = this.insertUserShoppingRelation(addRequest);
    		ShoppingCart shoppingCart = this.mergeShoppingCart(relation.getId(),addRequest);
    		JSONObject map = JSONObject.parseObject(addRequest.toString());
    		requestApiHelper.addShoppingCartSnap(map);
    		this.updateUserShoppingRelationNumber(relation);
    		
			response.setInfo(shoppingCart);
	        response.setTip("用户购物车添加成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
	}
	
	/**
     * 批量添加购物车商品
     */
	@Override
	public Response batchInsert(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		UserShoppingCartBatchAddRequest batchAddRequest = (UserShoppingCartBatchAddRequest)request;
    	try {
    		//校验购物车记录添加状态
    		shoppingCartAsync(batchAddRequest.getUserId(), batchAddRequest.getUserTraceId(), batchAddRequest.getApplicablePlatformId());
    		List<UserShoppingCartAddRequest> list = this.formatBatchAdd(batchAddRequest);
    		for (UserShoppingCartAddRequest addRequest : list) {
    			UserShoppingRelation relation = this.insertUserShoppingRelation(addRequest);
        		this.mergeShoppingCart(relation.getId(),addRequest);
        		this.updateUserShoppingRelationNumber(relation);
			}
	        response.setTip("用户购物车添加成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
	}
	
	private List<UserShoppingCartAddRequest> formatBatchAdd(UserShoppingCartBatchAddRequest batchAddRequest) throws Exception {
		List<UserShoppingCartAddRequest> list = new ArrayList<UserShoppingCartAddRequest>();
		int shoppingCartId = batchAddRequest.getShoppingCartId();
	    int userId = batchAddRequest.getUserId();
	    int applicablePlatformId = batchAddRequest.getApplicablePlatformId();
	    int subApplicablePlatformId = batchAddRequest.getSubApplicablePlatformId();
	    String userTraceId = batchAddRequest.getUserTraceId(); 
	    String expandCode = batchAddRequest.getExpandCode();
	    String subExpandCode = batchAddRequest.getSubExpandCode();
	    JSONArray goods = JSONArray.parseArray(batchAddRequest.getGoods());
	    for (int i=0; i<goods.size(); i++) {
	    	JSONObject object = goods.getJSONObject(i);
	    	UserShoppingCartAddRequest addRequest = new UserShoppingCartAddRequest();
	    	addRequest.setApplicablePlatformId(applicablePlatformId);
	    	addRequest.setAutoprompting(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.autoprompting.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.autoprompting.getParamName()));
	    	addRequest.setBrandId(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.goodsBrandId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.goodsBrandId.getParamName()));
	    	addRequest.setCatIds(object.getString(ApiUrlParamEnum.goodsCatIds.getParamName()));
	    	addRequest.setCreateType(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.createType.getParamName())) ? ShoppingCartCreateTypeEnum.CREATE_TYPE_MANUAL.getId() : object.getInteger(ApiUrlParamEnum.createType.getParamName()));	
	    	addRequest.setExpandCode(expandCode);
	    	addRequest.setFamilyMemberId(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.familyMemberId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.familyMemberId.getParamName()));
	    	int goodsId = StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.goodsId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.goodsId.getParamName());
			int mealId = StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.mealId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.mealId.getParamName());
			if ( goodsId < 1 && mealId < 1) {
				throw new ServiceOperationException("error goodsId or mealId: " + goodsId + ","+mealId);
			}
	    	addRequest.setGoodsId(goodsId);
	    	addRequest.setMealId(mealId);
	    	addRequest.setGoodsStatus(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.goodsStatus.getParamName())) ? GoodsStatusEnum.NORMAL.getId() : object.getInteger(ApiUrlParamEnum.goodsStatus.getParamName()));
	    	addRequest.setIconLabel(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.iconLabel.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.iconLabel.getParamName()));
	    	addRequest.setIsChecked(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.isChecked.getParamName())) ? GoodsCheckStatusEnum.CHECKED_NO.getId() : object.getInteger(ApiUrlParamEnum.isChecked.getParamName()));
	    	addRequest.setIsSeckill(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.isSeckill.getParamName())) ? FullGoodsStatusEnum.GOODS_NOT_SECKILL.getId() : object.getInteger(ApiUrlParamEnum.isSeckill.getParamName()));
	    	addRequest.setMerchantId(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.merchantId.getParamName())) ? 1 :object.getInteger(ApiUrlParamEnum.merchantId.getParamName()));
	    	addRequest.setNumber(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.number.getParamName())) ? 1 : object.getInteger(ApiUrlParamEnum.number.getParamName()));
	    	addRequest.setNumberLowerLimit(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.numberLowerLimit.getParamName())) ? 1 : object.getInteger(ApiUrlParamEnum.numberLowerLimit.getParamName()));
	    	addRequest.setNumberUpperLimit(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.numberUpperLimit.getParamName())) ? 2000 : object.getInteger(ApiUrlParamEnum.numberUpperLimit.getParamName()));
	    	addRequest.setOriginalGoodsId(StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.originalGoodsId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.originalGoodsId.getParamName()));
	    	double price = StringUtil.isEmpty(object.getDouble(ApiUrlParamEnum.goodsPrice.getParamName())) ? 0.0 : object.getDouble(ApiUrlParamEnum.goodsPrice.getParamName());
	    	if (price < 0) {
	    		throw new ServiceOperationException("error price: " + price);
	    	}
	    	addRequest.setPrice(price);
	    	addRequest.setProductCode(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.productCode.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.productCode.getParamName()));
	    	addRequest.setRemark(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.remark.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.remark.getParamName()));
	    	addRequest.setSalesMode(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.salesMode.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.salesMode.getParamName()));
	    	addRequest.setShoppingCartId(shoppingCartId);
	    	Integer skuId = StringUtil.isEmpty(object.getInteger(ApiUrlParamEnum.skuId.getParamName())) ? 0 : object.getInteger(ApiUrlParamEnum.skuId.getParamName());
			if(skuId < 1){
				throw new ServiceOperationException("error skuId:"+skuId);
			}
	    	addRequest.setSkuId(skuId);
	    	addRequest.setSpecialAttr(StringUtil.isEmpty(object.getString(ApiUrlParamEnum.specialAttr.getParamName())) ? "-" : object.getString(ApiUrlParamEnum.specialAttr.getParamName()));
	    	addRequest.setSubApplicablePlatformId(subApplicablePlatformId);
	    	addRequest.setSubExpandCode(subExpandCode);
	    	addRequest.setTags(object.getString(ApiUrlParamEnum.tags.getParamName()));
	    	addRequest.setUserId(userId);
	    	addRequest.setUserTraceId(userTraceId);
	    	list.add(addRequest);
	    } 
	    return list;
	}
	
	/**
	 * 修改用户购物车中的商品总数
	 * @param relation
	 */
	private void updateUserShoppingRelationNumber(UserShoppingRelation relation){
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqShoppingCartId", relation.getId());
		params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
		
		Integer sum = shoppingCartDao.selectSumNumberByMap(params);
		if(sum == null)
			sum = 0;
		relation.setNumber(sum);
		userShoppingRelationDao.update(relation);
	}
	
	/**
	 * 添加商品（支持游客购物车添加）
	 * @param addRequest
	 * @return
	 * @throws Exception 
	 */
	private ShoppingCart mergeShoppingCart(Integer shoppingCartId , UserShoppingCartAddRequest addRequest) throws Exception{
		ShoppingCart object = new ShoppingCart();
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", addRequest.getApplicablePlatformId());
		params.put("eqShoppingCartId", shoppingCartId);
		params.put("eqSkuId", addRequest.getSkuId());
		params.put("eqMealId", addRequest.getMealId());
		if(addRequest.getUserId() > 0)
			params.put("eqUserId", addRequest.getUserId());//登录用户
		else
			params.put("eqUserTraceId", addRequest.getUserTraceId());//游客用户
		params.put("eqFamilyMemberId", addRequest.getFamilyMemberId());
		params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
		params.put("eqExpandCode", addRequest.getExpandCode());//渠道
		params.put("eqSubExpandCode", addRequest.getSubExpandCode());//子渠道
		PageList<ShoppingCart> shoppingCartList = shoppingCartDao.selectByMap(params, 1, 1, false);
		
		//判断如果已经存在 则更新数量
		//如果不存在 则新增
		if(shoppingCartList.size() > 0){
			object = shoppingCartList.get(0);
			//数量递增
			int num = object.getNumber() + addRequest.getNumber();
			//注意商品上下限问题
			if(num > addRequest.getNumberUpperLimit())
				object.setNumber(num);
			else if(num < addRequest.getNumberLowerLimit())
				object.setNumber(addRequest.getNumberLowerLimit());
			else
				object.setNumber(num);
			
			if(!StringUtil.isEmpty(addRequest.getExpandCode())) {
				object.setExpandCode(addRequest.getExpandCode());
			}
			if(!StringUtil.isEmpty(addRequest.getSubExpandCode())) {
				object.setSubExpandCode(addRequest.getSubExpandCode());
			}
			object.setNumberUpperLimit(addRequest.getNumberUpperLimit());
			object.setNumberLowerLimit(addRequest.getNumberLowerLimit());
			object.setUpdateTime(new Date());
			shoppingCartDao.update(object);
		}else{
			object.setApplicablePlatformId(addRequest.getApplicablePlatformId());
			object.setAutoprompting(addRequest.getAutoprompting());
			object.setCreateType(addRequest.getCreateType());
			object.setFamilyMemberId(addRequest.getFamilyMemberId());
			object.setSkuId(addRequest.getSkuId());
			object.setGoodsId(addRequest.getGoodsId());
			object.setGoodsStatus(addRequest.getGoodsStatus());
			object.setIconLabel(addRequest.getIconLabel());
			object.setIsChecked(addRequest.getIsChecked());
			object.setMerchantId(addRequest.getMerchantId());
			object.setExpandCode(addRequest.getExpandCode());
			object.setMealId(addRequest.getMealId());
			object.setIsSeckill(addRequest.getIsSeckill());
			if(addRequest.getNumber() > addRequest.getNumberUpperLimit())
				object.setNumber(addRequest.getNumberUpperLimit());
			else if(addRequest.getNumber() < addRequest.getNumberLowerLimit())
				object.setNumber(addRequest.getNumberLowerLimit());
			else
				object.setNumber(addRequest.getNumber());
			object.setNumberUpperLimit(addRequest.getNumberUpperLimit());
			object.setNumberLowerLimit(addRequest.getNumberLowerLimit());
			object.setOriginalGoodsId(addRequest.getOriginalGoodsId());
			object.setProductCode(addRequest.getProductCode());
			object.setRemark(addRequest.getRemark());
			object.setSalesMode(addRequest.getSalesMode());
			object.setShoppingCartId(shoppingCartId);
			object.setSpecialAttr(addRequest.getSpecialAttr());
			if(!StringUtil.isEmpty(addRequest.getSubExpandCode())) {
				object.setSubExpandCode(addRequest.getSubExpandCode());
			}
			if(addRequest.getUserId() > 0)
				object.setUserId(addRequest.getUserId());//登录用户
			else
				object.setUserTraceId(addRequest.getUserTraceId());//游客用户
			shoppingCartDao.insert(object);
		}
		return object;
	}
	
	/**
	 * 添加购物车
	 * @param addRequest
	 * @return
	 */
	private UserShoppingRelation insertUserShoppingRelation(UserShoppingCartAddRequest addRequest){
		UserShoppingRelation relation = null;
		if(addRequest.getShoppingCartId() > 0)
			relation = userShoppingRelationDao.selectById(addRequest.getShoppingCartId());
		else{
			//避免有些调用方，忘记传递shoppingCartId,可以通过平台id和用户id进行查询，保证在每个平台下面只有一条记录
			HashMap<String,Object> params = new HashMap<String, Object>();
			params.put("eqApplicablePlatformId", addRequest.getApplicablePlatformId());
			if(addRequest.getUserId() > 0)
				params.put("eqUserId", addRequest.getUserId());//登录用户
			else
				params.put("eqUserTraceId", addRequest.getUserTraceId());//游客用户

			PageList<UserShoppingRelation> userShoppingRelationList = userShoppingRelationDao.selectByMap(params, 1, 1 , false);
    		if(userShoppingRelationList.size() == 1)
    			relation = userShoppingRelationList.get(0);
		}
		
		if(relation == null){
			relation = new UserShoppingRelation();
			relation.setApplicablePlatformId(addRequest.getApplicablePlatformId());
			
			if(addRequest.getUserId() > 0)
				relation.setUserId(addRequest.getUserId());//登录用户
			else
				relation.setUserTraceId(addRequest.getUserTraceId());//游客用户
			
			
			userShoppingRelationDao.insert(relation);
		}
		return relation;
	}
	
	@Override
	/**
	 * 修改购物车商品数量
	 */
	public Response update(Request request) throws Exception {
		UpdateResponse<ShoppingCart> response = new UpdateResponse<ShoppingCart>();
		UserShoppingCartUpdateRequest updateRequest = (UserShoppingCartUpdateRequest)request;
		int addNum = 0;
    	
		try {
    		ShoppingCart shoppingCart = shoppingCartDao.selectById(updateRequest.getId());
    		if(shoppingCart == null)
    			throw new ServiceOperationException("请求处理失败：查找不到相关信息");
    		
    		if(shoppingCart.getUserId().intValue() != updateRequest.getUserId() && !shoppingCart.getUserTraceId().equals(updateRequest.getUserTraceId()))
    			throw new ServiceOperationException("请求处理失败：用户id不匹配");
    		
    		if(shoppingCart.getNumberLowerLimit() > updateRequest.getNumber())
    			throw new ServiceOperationException("请求处理失败：购买的商品数不能低于最低要求的购买数");
    		
    		//修改购物车商品数量
    		
			//注意商品上下限问题
			if(updateRequest.getNumber() > shoppingCart.getNumberUpperLimit()) {
				addNum = shoppingCart.getNumberUpperLimit() - shoppingCart.getNumber();
				shoppingCart.setNumber(shoppingCart.getNumberUpperLimit());
				
			} else if(updateRequest.getNumber() < shoppingCart.getNumberLowerLimit()) {
				addNum = shoppingCart.getNumberLowerLimit() - shoppingCart.getNumber();
				shoppingCart.setNumber(shoppingCart.getNumberLowerLimit());
				
			} else {
				addNum = updateRequest.getNumber() - shoppingCart.getNumber();
				shoppingCart.setNumber(updateRequest.getNumber());
			}
			
			shoppingCart.setUpdateTime(new Date());
    		shoppingCartDao.update(shoppingCart);

    		//修改购物车总商品数量
    		UserShoppingRelation relation = userShoppingRelationDao.selectById(shoppingCart.getShoppingCartId());    		
    		this.updateUserShoppingRelationNumber(relation);
    		
    		//调用促销中心接口，添加
    		if(addNum > 0) {
    			UserShoppingCartAddRequest addRequest = new UserShoppingCartAddRequest();
    			addRequest.setMealId(shoppingCart.getMealId());
    			addRequest.setNumber(addNum);
    			addRequest.setUserId(updateRequest.getUserId());
    			addRequest.setSkuId(shoppingCart.getSkuId());
    			addRequest.setUserTraceId(updateRequest.getUserTraceId());
    			JSONObject map = JSONObject.parseObject(addRequest.toString());
    			requestApiHelper.addShoppingCartSnap(map);
    		}
			response.setInfo(shoppingCart);
	        response.setTip("用户购物车修改成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
	}
	
	@Override
	/**
	 * 删除购物车商品数量
	 */
	public Response delete(Request request) throws Exception {
		DeleteResponse<UserShippingAddress> response = new DeleteResponse<UserShippingAddress>();
		UserShoppingCartDeleteRequest deleteRequest = (UserShoppingCartDeleteRequest)request;
    	
		try {
			
			//如果为空，则表示购物车中的商品全部清空
			HashMap<String,Object> params = new HashMap<String, Object>();
			params.put("eqApplicablePlatformId",deleteRequest.getApplicablePlatformId() );
			
			if(!StringUtil.isEmpty(deleteRequest.getIds()))
				params.put("inIds", deleteRequest.getIds());
			
			if(deleteRequest.getUserId() > 0)
				params.put("eqUserId", deleteRequest.getUserId());//登录用户
			else
				params.put("eqUserTraceId", deleteRequest.getUserTraceId());//游客用户

			PageList<ShoppingCart> shoppingCartList = shoppingCartDao.selectByMap(params, 1, 1, false);
			
			if(shoppingCartList.size() == 1){
				params.put("status", deleteRequest.getStatus());
				params.put("updateTime", new Date());
				shoppingCartDao.updateByMap(params);
				
				//理论上删除的商品应该都是属于同一个购物车
				int shoppingCartId = shoppingCartList.get(0).getShoppingCartId();
	    		//修改购物车总商品数量
	    		UserShoppingRelation relation = userShoppingRelationDao.selectById(shoppingCartId);
	    		this.updateUserShoppingRelationNumber(relation);
	    		JSONObject object = JSONObject.parseObject(deleteRequest.toString());
	    		requestApiHelper.removeShoppingCartSnap(shoppingCartList.get(0).getMealId(),shoppingCartList.get(0).getSkuId(), object);
			}
	        response.setTip("用户购物车删除成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
	}
	
	
	private PageList<ShoppingCart> getVisitorShoppingCartList(UserShoppingCartMergeRequest mergeRequest){
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", mergeRequest.getApplicablePlatformId());
		params.put("eqUserTraceId", mergeRequest.getUserTraceId());//游客用户
		params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
		return shoppingCartDao.selectByMap(params, 1, 3000,false);
	}
	
	private UserShoppingRelation insertUserShoppingRelation(PageList<UserShoppingRelation> userShoppingRelationList ,UserShoppingCartMergeRequest mergeRequest){
		//如果原先该登录用户没有购物车，则新增
		UserShoppingRelation relation = new UserShoppingRelation();
		relation.setApplicablePlatformId(mergeRequest.getApplicablePlatformId());
		relation.setNumber(0);
		relation.setUserId(mergeRequest.getUserId());
		userShoppingRelationDao.insert(relation);
		return relation;
	}
	
	private void deleteUserShoppingRelation(UserShoppingCartMergeRequest mergeRequest){
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", mergeRequest.getApplicablePlatformId());
		params.put("eqUserTraceId", mergeRequest.getUserTraceId());
		userShoppingRelationDao.deleteByMap(params);
	}
	
	private void mergeShoppingCart(Integer userShoppingCartId ,PageList<ShoppingCart> visitorShoppingCartList ,UserShoppingCartMergeRequest mergeRequest){
		//1.查询出这个登录用户购物车中的所有商品
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", mergeRequest.getApplicablePlatformId());
		params.put("eqUserId", mergeRequest.getUserId());
		params.put("eqStatus", ShoppingCartStatusEnum.STATUS_NORMAL.getId());
		PageList<ShoppingCart> userShoppingCartList = shoppingCartDao.selectByMap(params, 1, 10000,false);
		Map<String,ShoppingCart> shoppingCartMap = new HashMap<String,ShoppingCart>();

		for(ShoppingCart cart : userShoppingCartList){
			String key = StringUtil.md5(cart.getGoodsId()+"_"+cart.getMealId()+"_"+cart.getSkuId()+"_"+cart.getExpandCode()+"_"+cart.getSubExpandCode());
			shoppingCartMap.put(key, cart);
		}	

		//2.合并，修改
		List<ShoppingCart> updateList = new ArrayList<ShoppingCart>();
		for(ShoppingCart visitorCart : visitorShoppingCartList){
			String key = StringUtil.md5(visitorCart.getGoodsId()+"_"+visitorCart.getMealId()+"_"+visitorCart.getSkuId()+"_"+visitorCart.getExpandCode()+"_"+visitorCart.getSubExpandCode());
			ShoppingCart userCart = shoppingCartMap.get(key);
			if(userCart == null){
				visitorCart.setUserId(mergeRequest.getUserId());
				visitorCart.setUserTraceId("-");
				visitorCart.setUpdateTime(new Date());
				visitorCart.setShoppingCartId(userShoppingCartId);
				updateList.add(visitorCart);
			}else{
				if(userCart.getNumberUpperLimit() < userCart.getNumber() + visitorCart.getNumber()){
					userCart.setNumber(userCart.getNumberUpperLimit());
				}else{
					userCart.setNumber(userCart.getNumber() + visitorCart.getNumber());
				}
				userCart.setUpdateTime(new Date());
				updateList.add(userCart);	
			}
		}
		shoppingCartDao.batchUpdateById(updateList);
		JSONObject object = JSONObject.parseObject(mergeRequest.toString());
		requestApiHelper.mergeShoppingCartSnap(object, userShoppingCartList.size()==0?1:0,
						visitorShoppingCartList.size() ==0?1:0);
	}
	
	private void deleteShoppingCart(UserShoppingCartMergeRequest mergeRequest){
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", mergeRequest.getApplicablePlatformId());
		params.put("eqUserTraceId", mergeRequest.getUserTraceId());//游客用户
		shoppingCartDao.deleteByMap(params);
	}
	
	private UserShoppingRelation getUserShoppingRelation(UserShoppingCartMergeRequest mergeRequest){
		HashMap<String,Object> params = new HashMap<String, Object>();
		params.put("eqApplicablePlatformId", mergeRequest.getApplicablePlatformId());
		params.put("eqUserId", mergeRequest.getUserId());
		PageList<UserShoppingRelation> userShoppingRelationList = userShoppingRelationDao.selectByMap(params, 1, 1 , false);

		UserShoppingRelation relation = new UserShoppingRelation();
		//如果userShoppingRelationList 为空，表示用户没有过购物车，则需要新增
		if(userShoppingRelationList.size() == 0){
			relation = this.insertUserShoppingRelation(userShoppingRelationList, mergeRequest);
		}
		else{
			relation = userShoppingRelationList.get(0);
		}

		return relation;
	}
	
	@Override
	/**
	 * 合并购物车商品数量
	 */
	public Response merge(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		UserShoppingCartMergeRequest mergeRequest = (UserShoppingCartMergeRequest)request;
    	
		try {
			PageList<ShoppingCart> visitorShoppingCartList = this.getVisitorShoppingCartList(mergeRequest);
			if(visitorShoppingCartList.size() == 0){
				log.error("func[merge] error[游客购物车中无商品]");
			}
			else{	
				//删除游客购物车
	    		this.deleteUserShoppingRelation(mergeRequest);
				
				//获取当前登录用户的购物车（每个平台每个用户只会有0个或1个购物车）
				UserShoppingRelation relation = this.getUserShoppingRelation(mergeRequest);
				
				//合并购物车中细项
				this.mergeShoppingCart(relation.getId() ,visitorShoppingCartList, mergeRequest);
				
	    		//删除游客购物车中的细项
	    		this.deleteShoppingCart(mergeRequest);
	    		
	    		//修改登录用户购物车总商品数量
	    		this.updateUserShoppingRelationNumber(relation);
			}
			response.setTip("用户购物车合并成功");
	    } catch (Exception e) {
	    	log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
	    return response;
	}
	
	/**
	 * 检查用户购物车缓存同步状态,用于防止表单重复提交导致数据重复添加
	 * @param userId
	 * @param userTraceId
	 * @throws Exception 
	 */
	private synchronized void shoppingCartAsync(Integer userId, String userTraceId,
			Integer applicablePlatformId) throws Exception {
		String cacheKey = ""; 
		if(userId > 0) {
			cacheKey = "CACHE_SHOPPINGCART_" + userId + "_" + applicablePlatformId; 
		} else {
			cacheKey = "CACHE_SHOPPINGCART_" + userTraceId + "_" + applicablePlatformId; 
		}
		do {
			if(null != cache.get(cacheKey)) {
				log.info("func[shoppingCartAsync] 用户购物车操作进程未完成，请求频率过频繁");
				throw new Exception("请求频率太频繁，请稍后访问");
			} else {
				cache.put(cacheKey, 1, this.cacheLifeCycle);
				return;
			}
		}while(true);
	}
}